-
Notifications
You must be signed in to change notification settings - Fork 8.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FABGW-20 Specify endorsing organizations #2578
Conversation
/ci-run |
internal/pkg/gateway/registry.go
Outdated
endorser *endorser | ||
endpoint string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As you introduced endorser
, can we remove endpoint
and use the endorser.address
instead? Same info in multiple form cause confusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good spot. Removed.
internal/pkg/gateway/registry.go
Outdated
peerGroup := groupPeers[0:quantity] | ||
r = append(r, peerGroup...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not related to this PR but a minor suggestion - A single letter variable works fine if the life of the variable spans a few lines (e.g., peerGroup
). The variable r
is declared far above from where it is used so a meaningful name would be better.
peerGroup := groupPeers[0:quantity] | |
r = append(r, peerGroup...) | |
r = append(r, groupPeers[0:quantity]...) |
} else { | ||
reg.logger.Warnf("Failed to find endorser at %s", peer.endpoint) | ||
} | ||
endorsers = append(endorsers, peer.endorser) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a clarification related to discovery - I assume that the assumption here is that a peer
does not appear in more than one groups for a given layout? Or this final slice can contain duplicates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's my assumption too. I followed the usage algorithm documented in the proto file:
https://github.com/hyperledger/fabric-protos/blob/main/discovery/protocol.proto#L175
My observation is that each group contains the peers of a single org, and the layouts give the various permutations of those orgs/groups
internal/pkg/gateway/registry.go
Outdated
if len(endorsingOrgs) == 0 || contains(endorsingOrgs, endorser.mspid) { | ||
groupPeers = append(groupPeers, &endorserState{peer: peer, endorser: endorser, endpoint: endpoint, height: height}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that we should discuss the semantics of user supplied endorsingOrgs
little more clearly. The endorsement policies are specified at the chaincode level and could possibly be overwritten at the collection level. In addition, my understanding was that the purpose of this third option was to allow apps to specify the names of the orgs explicitly and this option (instead of knowing the names of the collections) would be helpful for some apps . In other words, the app explicitly supplies an AND
policy and the assumption is that the app knows that the supplied AND
policy is a superset of the union of all policies for the collections that the transaction writes into. However, the semantics of the implementation here is that the app is supposed to supply an AND
policy that we would be intersect with chaincode level policy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The endorsers service discovery query takes into consideration both the chaincode level and collection level endorsement policy. But Manish is correct, we need to discuss the semantics of endorsingOrgs.
I think the primary use case is when the application knows exactly which orgs to target. In that case, the Service Discovery peers query should be utilized, rather than the more expensive endorsers query. This will often be the case when using state-based endorsement (as SD endorsers query doesn't consider state-based endorsement requirements). See more history in https://jira.hyperledger.org/browse/FABN-1601.
Another use case is when the endorsement policy should be used (for example 3 out of 100 orgs), but you want to target some specific orgs, for example you want to utilize OrgA and OrgB but let service discovery pick any third org.
Bret implemented both approaches for the node SDK, and I think we have to do the same for Gateway.
A note on the endorsers query org filtering approach... Bret used a client side endorsers query filter in node SDK , but that approach doesn't work at all when there are many layouts returned since service discovery may only return a random subset. That means you may entirely miss on the intersection of layouts returned and orgs required. The filter therefore must be done on the service discovery side - we need to consider extending the SD endorsers query to take the list of required orgs. In fact, this is why we have a single team responsible for Gateway and Service Discovery now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reimplemented this as Dave suggests to return all the peers from the list of 'endorsingOrganizations' that have the given chaincode installed.
81c1842
to
7801a1f
Compare
internal/pkg/gateway/registry.go
Outdated
return nil, fmt.Errorf("failed to select a set of endorsers that satisfy the endorsement policy") | ||
} | ||
|
||
// endorsersForOrgs returns a set of endorsers oen by the given orgs for the given chaincode on a channel. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does "oen" mean?
} | ||
|
||
var endorsers []*endorser | ||
members := reg.discovery.PeersOfChannel(common.ChannelID(channel)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing to be done in this PR, However, just to take a note, this appears to be case to revisit if the discovery api/code could be extended to take the org names as a filter that could improve the efficiency of this as compared to get all the peers and iterate over to filter.
internal/pkg/gateway/registry.go
Outdated
for _, installedChaincode := range member.Properties.Chaincodes { | ||
// only consider the peers that have our chaincode installed | ||
if installedChaincode.Name == chaincode { | ||
endorsers = append(endorsers, endorser) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like the existing function, I was expecting here as well - only one peer (with the maximum height) for one org. Am I missing something?
internal/pkg/gateway/registry.go
Outdated
if len(es) > 0 { | ||
endorsers = append(endorsers, es[0].endorser) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it a noop check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If, for any reason, the endorser returned by the discovery service is not in the gateway registry, then this could be an empty array. Perhaps if a new endorser had just come online and not been added to the registry yet. There's still a TODO comment in registerChannels()
to handle this type of dynamic update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed offline and @andrew-coleman is going to push a new patch. Holding it from merging for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Manish, I've added an error check that will report which orgs fail to find endorsing peers, and added extra unit tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on off-line discussion, expecting a minor fix and test for handling the case of insufficient available peers
Implementation of endorsingOrgs in gateway Endorse method. - The set of endorsing peers from the discovery service is filtered down to only include those from the specified orgs. - The discovery handling code has been upgraded to step through all given layouts to find a layout that satisfies the endorsingOrgs constraint. Signed-off-by: andrew-coleman <[email protected]>
Implementation of endorsingOrgs in gateway Endorse method.
Signed-off-by: andrew-coleman [email protected]